﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EBookStore.Publishers;
using EBookStore.Orders;
using EBookStore.Books;


namespace EBookStore.Management
{
    /// <summary>
    /// Singleton class
    /// </summary>
    public class PublisherManager
    {
        #region Properties

        private List<Publisher> _publishers;
        private List<BookAndAmount> _booksFromPublisher;

        /// <summary>
        /// used to emulate trigger of Books when they arrive from publisher
        /// </summary>
        public List<BookAndAmount> BooksArrivedFromPublisher {
            get
            {
                return _booksFromPublisher;                
            }           
        }

        /// <summary>
        /// List of publishers
        /// </summary>
        public List<Publisher> Publishers { get { return _publishers; } }
        
        #endregion
        
        #region Singleton
        private static PublisherManager _instance = null;
        private static object _syncObj = new object();



        /// <summary>
        /// PublisherManager instance
        /// </summary>
        public static PublisherManager Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_syncObj)
                    {
                        if (_instance == null)
                        {
                            _instance = new PublisherManager();
                        }
                    }
                }
                return _instance;
            }
        }


        private PublisherManager()
        {
            _publishers = new List<Publisher>();            
            _booksFromPublisher = new List<BookAndAmount>();
            //do initializations here if needed
        } 
        #endregion

        #region Public Functions


        public void AddBooksSuppliedByPublisher(BookAndAmount ba)
        {
            GetPublisher(ba.Book.PublisherID).SuppliedBooks += ba.Amount;            
        }


        /// <summary>
        /// add new publishers to instance
        /// </summary>
        /// <param name="publishers"></param>
        public void AddPublishers(IEnumerable<Publisher> publishers)
        {
            foreach (Publisher p in publishers)
            {
                AddPublisher(p);
            }
            
        }

        /// <summary>
        /// add single publisher
        /// </summary>
        /// <param name="p"></param>
        public void AddPublisher(Publisher p)
        {
            _publishers.Add(p);       
        }

        /// <summary>
        /// get publisher by ID
        /// </summary>
        /// <param name="PublisherID"></param>
        /// <returns></returns>
        public Publisher GetPublisher(string PublisherID)
        {
            return (from p in _publishers where p.ID== PublisherID select p).FirstOrDefault();
        }
        /// <summary>
        /// Delete publisher from instance
        /// </summary>
        /// <param name="publisherID"></param>
        public bool DeletePublisher(string publisherID)
        {
            return _publishers.RemoveAll(p => p.ID == publisherID) > 0;
        }

        /// <summary>
        /// order single book from publisher
        /// </summary>
        /// <param name="b">Book</param>
        /// <param name="amount"></param>
        /// <returns></returns>
        public bool OrderBook(Books.Book b, int amount)
        {
            IPublisher Action = new PublisherContactByFax();
            return Action.OrderBook( b, amount);
        }

        /// <summary>
        /// return book to publisher
        /// </summary>
        /// <param name="b">Book</param>
        /// <param name="amount"></param>
        /// <returns></returns>
        public bool ReturnBook(Books.Book b, int amount)
        {
            IPublisher Action = new PublisherContactByFax();
            return Action.OrderBook(b, amount);
        }
       
        #endregion  
   

        #region Clerk Functions

        public void Clear()
        {
            _publishers.Clear();
        }

        /// <summary>
        /// Count how many books are pending from certain publisher.
        /// </summary>
        /// <param name="pub"></param>
        /// <returns></returns>
        public int CountPendingBooksFromPublisher(Users.User u, Publisher pub)
        {
            if (u.GetType() != typeof(Users.Clerk))
            {
                throw new Exception("unAuthorized access");
            }
                        
            return (pub.OrderedBooks - pub.SuppliedBooks);

        }

        #endregion
    }
  
}
